package model;

import dao.DaoException;
import dao.DaoFactory;
import dao.FolderDao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

/**
 * 
 * This class is Folder model class
 * 
 * The folder class represents a folder object with its parameters.
 * @author Sukhjinder K. Narula (narula.sk@gmail.com)
 * @since May 2013
 * @version $Revision: 1.0 $
 */
public class Folder {
	
	// Dao
	private FolderDao dao;
	
	// Properties
	private int id;
	private String name;
	private int userId;
	private int parentId;
	private ArrayList<Email> emails;
	
	//	private String error;
	

	/**
	 * Constructor
	 * 
	
	
	
	 * @param name String
	 * @param userId int
	 * @param parentId int
	 */
	public Folder(String name, int userId, int parentId) {
		this.id = -1;
		this.name = name;
		this.userId = userId;
		this.parentId = parentId;
		this.emails = new ArrayList<Email>();
		this.dao = DaoFactory.getFolderDao();
	}
	
	/**
	 * Gets a folder id
	
	 * @return id: numeric unique value of the folder */
	public int getId() {
		return id;
	}

	/**
	 * Sets a folder id
	
	 * @param id int
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * Gets a folder name
	
	 * @return name: string value of the name of the folder */
	public String getName() {
		return name;
	}

	/**
	 * Sets a folder name
	
	 * @param name String
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Gets a user id
	
	 * @return userId: numeric unique value of the user id */
	public int getUserId() {
		return userId;
	}

	/**
	 * Sets the user id.
	
	 * @param userId int
	 */
	public void setUserId(int userId) {
		this.userId = userId;
	}
	
	/**
	 * Gets the parent folder id
	
	 * @return parentId: numeric unique value of the parent folder id */
	public int getParentId() {
		return parentId;
	}

	/**
	 * Sets the parent folder id
	
	 * @param parentId int
	 */
	public void setParentId(int parentId) {
		this.parentId = parentId;
	}
	
	/**
	 * Returns the hash map representation of properties
	
	 * @return HashMap<String,String>
	 */
	public HashMap<String, String> getTransferObject(){
		
		HashMap<String, String> toReturn = new HashMap<String, String>();
		toReturn.put("Id", String.valueOf(id));
		toReturn.put("Name", name);
		toReturn.put("UserId", String.valueOf(userId));
		toReturn.put("ParentId", String.valueOf(parentId));
		return toReturn;		
	}
	
	/**
	 * Saves (or creates new) folder into the database
	
	 * @throws ModelException */
	public void save() throws ModelException{
		
		if (id == -1){
			try {
				id = dao.create(getTransferObject());
			} catch (DaoException e) {
				throw new ModelException(e.getMessage());
			}
		} else {
			try {
				dao.update(getTransferObject());
			} catch (DaoException e) {
				throw new ModelException(e.getMessage());
			}
		}
	}
	
	/**
	 * Gets all emails belonging to the folder
	
	 * @return list of emails belonging to the current folder. */
	public List<Email> getEmails() {
		return emails;
	}
	
	/**
	 * Sets all emails belonging to the folder
	
	 * 
	 * @param list ArrayList<Email>
	 */
	public void setEmails(ArrayList<Email> list)
	{
		emails=list;
	}

	/**
	 * Delete all emails inside a folder
	
	 * @throws ModelException  */
	public void deleteEmails() throws ModelException {
		for (Email email : emails ){
			try {
				email.delete();
				
			} catch (DaoException e) {
				throw new ModelException("Could not delete email");
			}
		}
		emails.clear();
	}
	
	/**
	 * Given a list of ids, loops and deletes them from the emails list and also from db
	 * @param emailIdsToDelete
	
	 * @throws ModelException */
	public void deleteEmails(Set<Integer> emailIdsToDelete) throws ModelException{
		
		for (ListIterator<Email> iter = emails.listIterator(); iter.hasNext(); ){
			Email email = iter.next();
			if (emailIdsToDelete.contains(Integer.valueOf(email.getId()))){
				iter.remove();
			}
		}
		try {
			DaoFactory.getEmailDao().deleteById(emailIdsToDelete);
		} catch (DaoException e) {
			throw new ModelException(e.getMessage());
		}
	}

	/**
	 * Deletes the current folder from the database
	
	 * @throws ModelException  */
	public void delete() throws ModelException {
		try {
			dao.delete(id);
		} catch (DaoException e) {
			throw new ModelException(e.getMessage());
		}
	}

	
	/**
	 * Loops through the whole folder and gets the particular email
	 * @param emailId
	
	 * @return specific email object */
	public Email getEmail(int emailId) {
		
		for( Email email : emails){
			if (email.getId() == emailId){
				return email;
			}
		}
		return null;
	}
	
	/**
	 * Changes the folder of existing emails, and then removes it from it's own list
	
	
	
	 * @param emailIdsToMove Set<Integer>
	 * @param destinationFolder Folder
	 * @throws ModelException  */
	public void moveEmails(Set<Integer> emailIdsToMove, Folder destinationFolder) throws ModelException{
		
		for (ListIterator<Email> iter = emails.listIterator(); iter.hasNext(); ){
			Email email = iter.next();
			if (emailIdsToMove.contains(Integer.valueOf(email.getId()))){
				iter.remove();								// removing from own emails list
				destinationFolder.getEmails().add(email);	// adding to another folder
			}
		}
		try {
			DaoFactory.getEmailDao().updateFolderId(emailIdsToMove, destinationFolder.getId());
		} catch (DaoException e) {
			throw new ModelException(e.getMessage());
		}
	}
	
}
